/*
 Xern Entity Relocation Network
 Copyright (C) 2010-2011 Ronie Salgado <roniesalg@gmail.com>

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
*/

// Primitive implementation is heavily (practically a port/adaptation)
// based in the Meshmerizer of LibOpenMetaverse written
// by dahlia <dahliatrimble@gmail.com>

#ifndef XERN_PRIMITIVE_HPP
#define XERN_PRIMITIVE_HPP

#include "Xern/IProceduralPrimitive.hpp"
#include "Geometry.hpp"

namespace XernOgre
{
	namespace PrimitiveData
	{
		class Triangle;
	};

	class Primitive: public Geometry, public virtual IProceduralPrimitive
	{
	public:
		Primitive(boost::shared_ptr<OgreRenderer> renderer,
				Ogre::SceneManager *scene, Ogre::MeshPtr mesh,
				int verticesWidth, int verticesHeight);
		~Primitive();

		const JsonObject &GetParameters() const;
		void SetParameters(const JsonObject &parameters);

		int GetSculptureType() const;
		void SetSculptureType(int type);

		boost::shared_ptr<ITexture> GetSculpture() const;
		void SetSculpture(boost::shared_ptr<ITexture> sculpt);

		void UploadVertices(int buffer, size_t len, const void *data);
	private:
		void ExtrudeLinear();
		void ExtrudeCircular();

		void BuildMesh(const std::vector<Vector3> &coords, const std::vector<Vector2> &texcoods,
				const std::vector<PrimitiveData::Triangle> &faces, int width, int height, bool flip);
		void BuildSculpture();

		JsonObject parameters;

		// Used for sculpted.
		int verticesWidth;
		int verticesHeight;
		int sculptureType;
		boost::shared_ptr<ITexture> sculpture;

		// Decoded parameters.
		int sides;
		int hollowSides;
		float profileHollow;
		float profileStart;
		float profileEnd;
		int twistBegin;
		int twistEnd;
		float topShearX;
		float topShearY;
		float pathCutBegin;
		float pathCutEnd;
		float dimpleBegin;
		float dimpleEnd;
		float skew;
		float holeSizeX;
		float holeSizeY;
		float taperX;
		float taperY;
		float radius;
		float revolutions;
		int stepPerRevolution;
		int profileCurve;
		int pathCurve;
		int holeType;

		Vector3 scale;
		Quaternion rotation;
	};
};

#endif // XERN_PRIMITIVE_HPP
